<template>
  <div class="login_container">
    <div class="login_box">
      <!-- 头像区域 -->
      <div class="avatar_box">
        <img src="@/assets/logo.png" alt />
      </div>
      <!-- 登陆表单区域：loginFormRef表单的实例对象；loginForm绑定表单；loginRules验证表单数据 -->
      <el-form class="login_form" ref="loginFormRef" :model="loginForm" :rules="loginFormRules">
        <!-- 用户名 -->
        <el-form-item prop="username">
          <!-- 验证规则加载 item 的 prop 里 -->
          <el-input prefix-icon="fa fa-user-circle" v-model="loginForm.username"></el-input>
        </el-form-item>
        <!-- 密码 -->
        <el-form-item prop="password">
          <el-input type="password" prefix-icon="fa fa-lock" v-model="loginForm.password"></el-input>
        </el-form-item>
        <!-- 按钮 -->
        <el-form-item class="btns">
          <el-button type="text" @click="addUserDialogVisible = true">注册新账号</el-button>
          <el-button type="primary" @click="loginValidation">登陆</el-button>
          <el-button type="info" @click="resetLoginForm">重置</el-button>
        </el-form-item>
      </el-form>
    </div>
    <!-- 弹出添加用户的对话框  -->
    <el-dialog title="添加用户" :visible.sync="addUserDialogVisible" width="50%" center>
      <!-- content:内部主体在该span内 -->
      <span>
        <!-- addForm:用户表单数据   addFormRules:表单的验证规则;  ref：该form表单引用名称 -->
        <el-form
          :model="addForm"
          status-icon
          :rules="addFormRules"
          ref="addFormRef"
          label-width="100px"
        >
          <el-form-item label="用户名" prop="username">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.username" placeholder="请输入用户名"></el-input>
          </el-form-item>
          <el-form-item label="身份权限" prop="role">
            <el-radio-group v-model="addForm.role">
              <el-radio :label="1">
                <el-tag :type="'danger'">管理员</el-tag>
              </el-radio>
              <el-radio :label="0">
                <el-tag :type="'success'">大会员</el-tag>
              </el-radio>
            </el-radio-group>
          </el-form-item>
          <el-form-item label="输入密码" prop="password">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.password" placeholder="请输入密码"></el-input>
          </el-form-item>
          <el-form-item label="确认密码" prop="checkpwd">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.checkpwd" placeholder="再次输入密码"></el-input>
          </el-form-item>
          <el-form-item label="联系方式" prop="phone">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.phone" placeholder="请输入联系方式"></el-input>
          </el-form-item>
          <el-form-item label="邮箱地址" prop="email">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.email" placeholder="请输入邮箱地址"></el-input>
          </el-form-item>
          <el-form-item label="密保问题" prop="question">
            <!-- prop:验证规则属性 -->
            <el-input type="text" v-model="addForm.question" placeholder="请输入密保问题"></el-input>
          </el-form-item>
          <el-form-item label="密保答案" prop="answer">
            <!-- prop:验证规则属性 -->
            <el-input type="password" v-model="addForm.answer" placeholder="请输入密保答案"></el-input>
          </el-form-item>
        </el-form>
      </span>
      <!-- 退出编辑的内嵌会话框 -->
      <el-dialog width="30%" title="是否退出编辑" :visible.sync="innerVisible" append-to-body center>
        <!-- footer: -->
        <span slot="footer" class="dialog-footer">
          <el-button type="primary" @click="innerVisibleClose">确 定</el-button>
        </span>
      </el-dialog>
      <!-- footer: -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="innerVisible = true">退出编辑</el-button>
        <el-button type="primary" @click="addUser">提 交</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 登陆表单的数据绑定对象；
      loginForm: {
        username: '',
        password: ''
      },
      // 内嵌框的状态
      innerVisible: false,
      addUserDialogVisible: false,
      // 表单的数据
      addForm: {
        username: '',
        role: 0,
        password: '',
        checkpwd: '',
        phone: 0,
        email: '',
        question: '',
        answer: ''
      },
      // 表单的验证规则对象
      addFormRules: {
        username: [
          // username的规则一
          {
            // 必填项？
            required: true,
            // 响应信息
            message: '请输入用户名',
            // 触发事件
            trigger: 'blur'
          },
          // username的规则二
          {
            // 最小长度
            min: 3,
            // 最大长度
            max: 9,
            // 信息
            message: '用户名的长度在3~9个字符之间',
            // 触发事件
            trigger: 'blur'
          },
          {
            validator: async (rule, value, callback) => {
              const { data: res } = await this.$axios.get('manage/user/check_valid', {
                params: {
                  str: value,
                  type: 'username'
                }
              })
              if (res.status !== 0) callback(new Error(res.msg))
              callback()
            },
            trigger: 'blur'
          }
        ],
        role: [
          {
            required: true
          }
        ],
        password: [
          {
            required: true,
            message: '请输入要设置的密码',
            trigger: 'blur'
          },
          {
            min: 6,
            max: 15,
            message: '密码长度在6~15个字符之间',
            trigger: 'blur'
          }
        ],
        checkpwd: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('请再次输入密码'))
              if (value !== this.addForm.password) callback(new Error('上下输入密码不一致'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        phone: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('必填项'))
              const v = /^1[3456789]\d{9}$/
              if (!v.test(value)) callback(new Error('请输入有效的手机号码'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        email: [
          {
            validator: async (rule, value, callback) => {
              if (value === '') callback(new Error('必填项'))
              const v = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
              if (!v.test(value)) callback(new Error('请输入有效的邮箱'))
              const { data: res } = await this.$axios.get('manage/user/check_valid', {
                params: {
                  str: value,
                  type: 'email'
                }
              })
              if (res.status !== 0) callback(new Error(res.msg))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ],
        question: [
          {
            required: true,
            message: '必填项',
            trigger: 'blur'
          },
          {
            min: 3,
            max: 20,
            message: '密保问题长度在3~20个字符之间',
            trigger: 'blur'
          }
        ],
        answer: [
          {
            validator: (rule, value, callback) => {
              if (value === '') callback(new Error('密保答案不能为空'))
              if (value === this.addForm.question) callback(new Error('密保答案不能与密保问题一致'))
              callback()
            },
            required: true,
            trigger: 'blur'
          }
        ]
      },
      // 表单的验证规则对象
      loginFormRules: {
        // key 与 el-form-item 的 prop 对应
        // 验证用户名是否合法
        username: [
          // 规则一：required:true 必填项；message:" " 返回信息；trigger触发事件是blur，即失去焦点时验证
          { required: true, message: '请输入登陆名称', trigger: 'blur' },
          // 规则二：min 最小长度；max 最大长度
          { min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur' }
        ],
        // 验证密码是否合法
        password: [
          { required: true, message: '请输入密码', trigger: 'blur' },
          { min: 5, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur' }
        ]
      }
    }
  },
  methods: {
    // 点击重置按钮，重置登陆表单内容与验证结果
    resetLoginForm() {
      // 表单实例的 resetFields 方法：对整个表单进行重置包括验证结果；
      // 表单实例的 validate 方法：对整个表单进行校验；
      // 表单实例的 validateField 方法：对部分表单字段进行校验；
      // 表单实例的 clearValidate 方法：移除表单项的校验结果。
      this.$refs.loginFormRef.resetFields()
    },
    loginValidation() {
      // 参数 => {方法体} 即 Lambda 表达式 ； 添加 async 异步请求
      this.$refs.loginFormRef.validate(async callback => {
        // callback 接收表单验证的结果;根据 callback 返回的 true/false 进行下一步操作
        if (!callback) return false
        // 发送一个 post 请求，url为 login ，参数为 loginForm 对象
        const info = new URLSearchParams() // 向后台传递form-data数据：步骤一
        info.append('username', this.loginForm.username)
        info.append('password', this.loginForm.password)
        this.$axios
          .post('manage/user/login', info, {
            headers: {
              'Content-Type': 'application/x-www-form-urlencoded' // 向后台传递form-data数据：步骤二
            }
          })
          .then(result => {
            // status == 0 错误代码 1 登陆成功
            if (result.data.status !== 0) {
              return this.$message.error(result.data.msg)
            }
            this.$message.success(result.data.msg)
            //  1. 登陆成功后，将token保存到客户端的 sessionStorage(session会话级别，local本地级别)
            //    1.1 项目中除了登陆之外的其他API接口，必需在登陆之后访问
            //    1.2 token只应在当前网站打开期间生效，所以将 token 存储在 sessionStorage中
            sessionStorage.setItem('CURRENT_TOKEN', result.data.data.token)
            //  2. 通过编程式导航跳转到后台主页
            if (result.data.data.info.role === 1) {
              this.$router.push('/home')
            } else if (result.data.data.info.role === 0) {
              this.$router.push('/main')
            } else {
              this.$message.error('未知身份，无法跳转下一个页面')
            }
          })
      })
    },
    // 是否退出编辑 内嵌框
    innerVisibleClose() {
      // 内嵌框 关闭
      this.innerVisible = false
      // 会话框 关闭
      this.addUserDialogVisible = false
      // 清楚会话框数据
      this.$refs.addFormRef.resetFields()
    },
    // 添加新用户
    addUser() {
      // 提交前预检
      this.$refs.addFormRef.validate(async valid => {
        // 如果valid预检false，直接返回
        if (!valid) return
        // 发送添加数据的请求
        const { data: res } = await this.$axios.post('manage/user/register_customer', this.addForm)
        // 添加失败
        if (res.status !== 0) return this.$message.error(res.msg)
        // 添加成功
        this.$message.success(res.msg)
        // 关闭对话框
        this.addUserDialogVisible = false
      })
    }
  }
}
</script>

<style lang="less" scoped>
.login_container {
  background-color: rgb(43, 101, 226);
  height: 100%;
}
.login_box {
  width: 500px;
  height: 300px;
  background-color: #ffffff;
  border-radius: 3px;
  position: absolute;
  top: 50%; //向下位移50%
  left: 50%; //向右位移50%
  transform: translate(-50%, -50%); //在横轴和纵轴位移50%
  //less嵌套
  .avatar_box {
    height: 150px;
    width: 150px;
    border: 1px solid #eeeeee;
    border-radius: 50%; //外框圆角45°，即圆形
    padding: 10px; //内边距
    box-shadow: 0 0 10px #ddd; //阴影
    position: absolute;
    left: 50%;
    transform: translate(-50%, -50%); //横轴纵轴各移动50%，基于自身宽高，-代表反向
    background-color: #ffffff;
    img {
      width: 100%;
      height: 100%;
      border-radius: 50%;
      background-color: gray;
    }
  }
}

.btns {
  display: flex; //弹性框模型
  justify-content: flex-end; //横轴上居右对齐
}

.login_form {
  position: absolute;
  bottom: 0;
  width: 100%;
  padding: 0 20px; // 这里input右边会溢出，将下列默认的context-box 改为 border-box
  box-sizing: border-box; // box-sizing 规定两个并排的带边框的框：默认content-box在宽高之外绘制元素的内边距和边框；border-box在已设定的宽高分别减去边框和内边距才能得到内容的宽高；inherit从父元素继承box-sizing属性的值.
}
</style>
